
#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>


namespace ThreadMoudle
{

    enum class TSTAUS
    {
        THREAD_NEW,
        THREAD_RUNNING,
        THREAD_STOP
    };
    int cnt = 0;

   
    using task = std::function<void(std::string)>;

    class Thread
    {
    public:
        static void *run(void *obj)
        {
            Thread *self = static_cast<Thread *>(obj);

            self->style = TSTAUS::THREAD_RUNNING;

            self->_func(self->GetName());//这里的调用可能会出错

            return nullptr;
        }

        void SetName()
        {
           _name = "Thread-" + std::to_string(cnt++);
        }

        // 线程默认为joinable
        Thread(task my_func) : _func(my_func), _joined(true), style(TSTAUS::THREAD_NEW)
        {
            SetName();
        }

        void EnableDeath()
        {
            if (style == TSTAUS::THREAD_NEW)
            {
                _joined = false;
            }
        }

        void EnableJoined()
        {
            if (style == TSTAUS::THREAD_NEW)
            {
                _joined = true;
            }
        }

        bool Start()
        {
            if (style == TSTAUS::THREAD_RUNNING)
            {
                return true;
            }
            int n = pthread_create(&_td, nullptr, run, this);
            if (n != 0)
                return false;
            return true;
        }

        bool Join()
        {
            if (_joined)
            {
                int n = pthread_join(_td, nullptr);
                if (n == 0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }

        ~Thread()
        {
            
        }

        std::string GetName() {
            return _name;
        }

    private:
        pthread_t _td;
        std::string _name;

        bool _joined;
        task _func;
        
        TSTAUS style;
    };

}